package com.lonewalker.sparrow.listener;

import cn.hutool.core.collection.CollUtil;
import com.alibaba.excel.context.AnalysisContext;
import com.alibaba.excel.exception.ExcelAnalysisStopException;
import com.alibaba.excel.exception.ExcelDataConvertException;
import com.alibaba.excel.read.listener.ReadListener;
import com.lonewalker.sparrow.entity.SysUser;
import lombok.extern.slf4j.Slf4j;

import java.util.ArrayList;
import java.util.List;
import java.util.function.Consumer;
import java.util.function.Predicate;

/**
 * @author lonewalker
 */
@Slf4j
public class UserReadListener implements ReadListener<SysUser> {

    private final int batchSize;
    private List<SysUser> cacheData;

    private Predicate<SysUser> predicate;
    private Consumer<List<SysUser>> consumer;

    public UserReadListener(Consumer<List<SysUser>> consumer){
        this(5,consumer);
    }

    public UserReadListener(int batchSize, Consumer<List<SysUser>> consumer){
        this.batchSize = batchSize;
        this.consumer = consumer;
        this.cacheData = new ArrayList<>(this.batchSize);
    }

    public UserReadListener(int batchSize, Predicate<SysUser> predicate, Consumer<List<SysUser>> consumer){
        this.batchSize = batchSize;
        this.predicate = predicate;
        this.consumer = consumer;
        this.cacheData = new ArrayList<>(this.batchSize);
    }

    @Override
    public void invoke(SysUser user, AnalysisContext analysisContext) {
        log.info("invoke : {}",user);
        this.cacheData.add(user);
        if (this.cacheData.size() >= this.batchSize){
            this.consumer.accept(this.cacheData);
            this.cacheData.clear();
        }
    }

    @Override
    public void doAfterAllAnalysed(AnalysisContext analysisContext) {
        log.info("doAfterAllAnalysed : {}",this.cacheData.size());
        if (CollUtil.isNotEmpty(this.cacheData)){
            this.consumer.accept(this.cacheData);
        }
    }

    @Override
    public void onException(Exception exception, AnalysisContext context) throws Exception {
        if (exception instanceof ExcelDataConvertException){
            ExcelDataConvertException convertException = (ExcelDataConvertException) exception;
            Integer rowIndex = convertException.getRowIndex();
            Integer columnIndex = convertException.getColumnIndex();
            String cellData = convertException.getCellData().getStringValue();
            String reason = exception.getMessage();
            log.error("第{}行,第{}列,单元格{},解析异常:{}",rowIndex, columnIndex, cellData, reason);
            throw new ExcelAnalysisStopException();
        }
        throw exception;
    }
}
